#-------------------------------------------------------------------------------
# Copyright (c) 2012 Huseyin BIYIK.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0
# which accompanies this distribution, and is available at
# http://www.gnu.org/licenses/gpl.html
# 
# Contributors:
#     Huseyin BIYIK - initial API and implementation
#-------------------------------------------------------------------------------
import pyaudio, audioop, time
from crowd.defs import *

class audio_interface():
	def __init__(self):
		self.channels = 1
		self.rate = 8000
		self.depth = 16
		self.codec = codec()
		try:
			self.p = pyaudio.PyAudio()
			self.stream = self.p.open(format=pyaudio.paInt16, channels=self.channels, rate=self.rate, input=True, output=True, frames_per_buffer=1024)
		except IOError, e:
			logger.error("Audio interface can not be initialized :  %s" , e)
			return None
		logger.info("Audio interface initialized")

	def close(self):
		try:
			self.stream.close()
		except IOError, e:
			logger.error("Audio interface can not be closed :  %s retrying" , e)
		return True

	def in_func(self, ms, max_len):
		try:
			chunk = self.ms2byte(ms)
			return self.codec.compress(self.stream.read(chunk)), time.time()

		except IOError, e:
			logger.error("Audio interface cant read %d ms stream: %s", ms,e)
			return "", time.time()

	def out_func(self, payload):
		audio = self.codec.decompress(payload)
		try:
			self.stream.write(audio)
			return self.byte2ms(audio), time.time()
		except IOError, e:
			logger.error("Audio interface cant write %d byte to stream: %s", asciisize(audio), e)
			return 0, time.time()

	def byte2ms(self, chunk):
			return float(len(chunk)) / float(self.rate * self.depth / 8) * 1000

	def ms2byte(self, time):
			return time * self.rate / 1000

class codec():
	def __init__(self):
		logger.info("Codecs initialized")
	def compress(self, audio):
		try:
			return audioop.lin2ulaw(audio, 2)
		except audioop.error, e:
			logger.error("Codec cant encode %d byte aduio : %s", asciisize(audio), e)
			return ""
	
	def decompress(self, payload):
		try:
			return audioop.ulaw2lin(payload, 2)
		except audioop.error, e:
			logger.error("Codec cant decode %d byte aduio : %s", asciisize(payload), e)
#			hex=binascii.hexlify(payload)
#			print str(len(hex)/2)+ " : " + str(hex)
#			print binascii.hexlify(payload[-1:])
			return ""
